package com.pig4cloud.pigx.contract.executer.trade.supporter;

import com.pig4cloud.pigx.common.customize.contants.SystemConfigConstants;
import com.pig4cloud.pigx.common.customize.utils.CommonUtil;
import com.pig4cloud.pigx.contract.bo.ContractTradeNewBO;
import com.pig4cloud.pigx.contract.entity.ContractOrder;
import com.pig4cloud.pigx.contract.entity.ContractPosition;
import com.pig4cloud.pigx.contract.executer.order.supporter.OrderCalculator;

import java.math.BigDecimal;

/**
 * 成交记录计算器
 *
 * @since 2022/9/11 14:04
 */
public class TradeCalculator {

	/**
	 * 处理开仓成交记录时，计算应消耗的保证金
	 * <p>做多：保证金 = 成交面值 / 杠杆倍数
	 * <p>做空：保证金 = 成交数量 / 订单数量 * 订单保证金
	 * <p>计算出来的保证金可能超过订单剩余冻结金额。超过时，使用订单剩余冻结金额
	 *
	 * @param bo 成交记录
	 * @return {@link BigDecimal}
	 * @since 2022/9/11 13:57
	 */
	public static BigDecimal getMarginWhenOpen(ContractTradeNewBO bo) {
		BigDecimal margin;

		// 做多
		if (bo.getIsLong()) {
			margin = OrderCalculator.getMargin(bo.getTradeValue(), bo.getMultiple());
		} else {
			// 做空
			margin = bo.getNum().divide(bo.getOrderNum(), SystemConfigConstants.amountScale, SystemConfigConstants.mainCurRoundingMode)
					.multiply(bo.getOrderMargin());
		}

		// 计算出来的保证金可能超过订单剩余冻结金额。超过时，使用订单剩余冻结金额
		ContractOrder order = bo.getOrder();
		if (margin.compareTo(order.getFrozenAmount()) > 0) {
			margin = order.getFrozenAmount();
		}

		// 设置精度，返回结果
		return CommonUtil.setUSDTScale(margin);
	}

	/**
	 * 处理平仓成交记录时，计算应归还的保证金
	 * <p>保证金 = 成交数量 / 持仓数量 * 持仓保证金
	 * <p>计算出来的保证金可能超过仓位剩余保证金。超过时，使用仓位剩余保证金
	 *
	 * @param bo 成交记录
	 * @return {@link BigDecimal}
	 * @since 2022/9/11 13:57
	 */
	public static BigDecimal getMarginWhenClose(ContractTradeNewBO bo) {
		ContractPosition position = bo.getPosition();

		BigDecimal margin = bo.getNum().divide(position.getNowNum(), SystemConfigConstants.amountScale, SystemConfigConstants.mainCurRoundingMode)
				.multiply(position.getMargin());

		// 计算出来的保证金可能超过仓位剩余保证金。超过时，使用仓位剩余保证金
		if (margin.compareTo(position.getMargin()) > 0) {
			margin = position.getMargin();
		}

		// 设置精度，返回结果
		return CommonUtil.setUSDTScale(margin);
	}
}
